import React, { useState, useCallback, useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import './style.scss';
import api, { host } from 'api/config';
import { toast } from 'react-toastify';

const ImageUpload = ({
    onFileChange,
    onFileDelete,
    initialImageUrl = '',
    className = '',
    accept = 'image/*',
    disabled = false,
    text = '上传参考图',
    showDelete = true,
}) => {
    const [imageUrl, setImageUrl] = useState(initialImageUrl);
    const [file, setFile] = useState(null);
    const [isBlobUrl, setIsBlobUrl] = useState(false); // 添加状态来跟踪是否为blob URL
    const inputref = useRef(null);
    const localBlobUrl = useRef(null); // 存储本地blob URL

    const isValidFileName = (filename) => {
        // 检查是否包含非法字符
        const invalidChars = ['@', ' '];
        return !invalidChars.some((char) => filename.includes(char));
    };

    // 处理文件选择
    const handleFileChange = useCallback(
        (e) => {
            const selectedFile = e.target.files[0];
            if (selectedFile) {
                // 在上传前检查文件名
                if (!isValidFileName(selectedFile.name)) {
                    toast.error(
                        '文件名包含非法字符 (@ 或空格)，请重新命名文件后再上传',
                        {
                            autoClose: 1000,
                            hideProgressBar: true,
                        }
                    );
                    // 重置input值
                    if (inputref.current) {
                        inputref.current.value = '';
                    }
                    return;
                }
                processFile(selectedFile);
            }
        },
        [onFileChange]
    );

    // 处理拖拽放下文件
    const handleDrop = useCallback(
        (e) => {
            e.preventDefault();
            const droppedFile = e.dataTransfer.files[0];
            if (droppedFile) {
                if (!isValidFileName(droppedFile.name)) {
                    toast.error(
                        '文件名包含非法字符 (@ 或空格)，请重新命名文件后再上传',
                        {
                            autoClose: 1000,
                            hideProgressBar: true,
                        }
                    );

                    return;
                }
                processFile(droppedFile);
            }
        },
        [onFileChange]
    );

    const uploadToOSS = async (file) => {
        const formData = new FormData();
        formData.append('file', file);

        const response = await api.post('/v1/tob/upload-image', formData, {
            headers: {
                'Content-Type': 'multipart/form-data',
            },
        });

        const result = await response.data;
        return result.url;
    };

    // 统一处理文件
    const processFile = async (file) => {
        setFile(file);

        // 立即创建本地预览
        if (localBlobUrl.current) {
            URL.revokeObjectURL(localBlobUrl.current); // 清理之前的blob URL
        }
        localBlobUrl.current = URL.createObjectURL(file);
        setImageUrl(localBlobUrl.current);
        setIsBlobUrl(true); // 标记为blob URL

        // 保存当前blob URL，用于后续比较
        const currentBlobUrl = localBlobUrl.current;

        // 开始上传到服务器
        try {
            const url = await uploadToOSS(file);

            // 检查当前显示的是否还是这个blob URL
            // 如果是，才替换为服务器URL
            if (
                imageUrl === currentBlobUrl ||
                localBlobUrl.current === currentBlobUrl
            ) {
                setImageUrl(url);
                setIsBlobUrl(false); // 标记为服务器URL
                onFileChange(file, url);
            }
        } catch (error) {
            // 只有当当前显示的还是这个blob URL时才显示错误
            if (
                imageUrl === currentBlobUrl ||
                localBlobUrl.current === currentBlobUrl
            ) {
                toast.error('图片上传失败，请重试', {
                    autoClose: 1000,
                    hideProgressBar: true,
                });
                // 上传失败时清除预览
                setImageUrl('');
                setIsBlobUrl(false); // 重置标记
                if (localBlobUrl.current) {
                    URL.revokeObjectURL(localBlobUrl.current);
                    localBlobUrl.current = null;
                }
                if (inputref.current) {
                    inputref.current.value = '';
                }
            }
        }
    };

    // 处理删除图片
    const handleDelete = useCallback(
        async (e) => {
            e.stopPropagation(); // 阻止事件冒泡

            // 清理本地blob URL
            if (localBlobUrl.current) {
                URL.revokeObjectURL(localBlobUrl.current);
                localBlobUrl.current = null;
            }

            // 重置标记
            setIsBlobUrl(false);

            // 清理状态
            setImageUrl('');
            setFile(null);

            if (onFileDelete) {
                onFileDelete(); // 通知父组件文件已被删除
            }

            // 重置input值，允许重复上传同一文件
            if (inputref.current) {
                inputref.current.value = '';
            }
        },
        [onFileDelete]
    );

    const handleDragOver = useCallback((e) => {
        e.preventDefault();
    }, []);

    useEffect(() => {
        if (initialImageUrl) {
            setImageUrl(initialImageUrl);
            setFile(null); // 重置file状态
            setIsBlobUrl(false); // 重置标记

            // 清理可能存在的本地blob URL
            if (localBlobUrl.current) {
                URL.revokeObjectURL(localBlobUrl.current);
                localBlobUrl.current = null;
            }
        }
    }, [initialImageUrl]);

    // 组件卸载时清理blob URL
    useEffect(() => {
        return () => {
            if (localBlobUrl.current) {
                URL.revokeObjectURL(localBlobUrl.current);
            }
        };
    }, []);

    return (
        <div
            className={`file-upload-container ${className}`}
            onDrop={handleDrop}
            onDragOver={handleDragOver}
        >
            <input
                type="file"
                accept={accept}
                onChange={handleFileChange}
                className="file-input"
                disabled={disabled}
                ref={inputref}
            />
            {imageUrl ? (
                <div className="image-preview">
                    <img
                        src={imageUrl}
                        alt="Preview"
                        style={{
                            opacity: isBlobUrl ? 0.3 : 1,
                            transition: 'opacity 0.2s ease',
                        }}
                    />
                    {showDelete && (
                        <button
                            className="delete-button"
                            onClick={handleDelete}
                            aria-label="删除图片"
                        >
                            <svg viewBox="0 0 24 24" width="16" height="16">
                                <path
                                    fill="currentColor"
                                    d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
                                />
                            </svg>
                        </button>
                    )}
                </div>
            ) : (
                <div className="file-upload-text">
                    <img
                        src="https://img.alicdn.com/imgextra/i4/O1CN01uFSjFw28m9JwLypRT_!!6000000007974-55-tps-16-14.svg"
                        alt="上传图标"
                    />
                    <p>{text}</p>
                </div>
            )}
        </div>
    );
};

ImageUpload.propTypes = {
    onFileChange: PropTypes.func.isRequired,
    onFileDelete: PropTypes.func,
    initialImageUrl: PropTypes.string,
    className: PropTypes.string,
    accept: PropTypes.string,
    disabled: PropTypes.bool,
    text: PropTypes.string,
    showDelete: PropTypes.bool,
};

export default ImageUpload;
